package com.alogic.xscript.plugins;

import com.alogic.load.Loader;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;

import com.alogic.validator.Validator;
import com.alogic.validator.ValidatorFactory;
import com.alogic.xscript.AbstractLogiclet;
import com.alogic.xscript.ExecuteWatcher;
import com.alogic.xscript.Logiclet;
import com.alogic.xscript.LogicletContext;
import com.alogic.xscript.doc.XsObject;
import com.anysoft.util.Properties;
import com.anysoft.util.PropertiesConstants;

/**
 * 验证是否取值是否合法
 * @author yyduan
 * @since 1.6.12.11 [20181206 duanyy] <br>
 *
 * @version 1.6.13.25 [20201110 duanyy] <br>
 * - 修复validator的问题
 */
public class Validate extends Segment{
	protected String $id;
	protected String validatorId = null;
	protected String $value;
	
	public Validate(String tag, Logiclet p) {
		super(tag, p);
	}

	@Override
	public void configure(Properties p) {
		super.configure(p);
		$id = PropertiesConstants.getRaw(p,"id","$" + this.getXmlTag());
		$value = PropertiesConstants.getRaw(p,"value","");
		validatorId = getValidatorId(p);
	}		
	
	protected String getValidatorId(Properties p){
		return PropertiesConstants.getString(p,"type",validatorId,true);
	}
	
	@Override
	protected void onExecute(final XsObject root, final XsObject current, final LogicletContext ctx,
							 final ExecuteWatcher watcher) {
		final String id = PropertiesConstants.transform(ctx, $id, "$" + this.getXmlTag());
		if (StringUtils.isNotEmpty(id)){
			String value = PropertiesConstants.transform(ctx, $value, "");
			boolean sucessful = true;
			if (StringUtils.isNotEmpty(value) && StringUtils.isNotEmpty(validatorId)){
				Loader<Validator> loader = ValidatorFactory.getDefault();
				if (loader != null) {
					Validator validator = loader.load(validatorId, true);
					if (validator != null) {
						final Validate self = this;
						sucessful = validator.check(value, ctx,new Validator.Listener(){
							@Override
							public boolean result(boolean pass, String value, Validator validator, Properties p) {
								String code = pass?Validator.OK_CODE:validator.getCode(p);
								String msg = validator.getMessage(p);

								ctx.SetValue(id + ".id.$",validatorId);
								ctx.SetValue(id + ".code.$", code);
								ctx.SetValue(id + ".reason.$", msg);

								if (!code.equals(Validator.OK_CODE)) {
									ctx.SetValue(id + ".code", code);
									ctx.SetValue(id + ".reason", msg);
								}
								self.onSuperExecute(root,current,ctx,watcher);
								return true;
							}
						});
					}
				}
			}
			ctx.SetValue(id, BooleanUtils.toStringTrueFalse(sucessful));
		}
	}

	protected void onSuperExecute(final XsObject root, final XsObject current, final LogicletContext ctx,
							 final ExecuteWatcher watcher) {
		super.onExecute(root,current,ctx,watcher);
	}
}
